package com.qining618.common.result;

import com.qining618.common.exception.BusinessException;
import lombok.*;
import lombok.experimental.Accessors;

import java.io.Serializable;
import java.util.Optional;

/**
 * @author iqiao
 * @date 2019/5/23 0023.
 */
@Data
@Builder
@ToString
@EqualsAndHashCode
@NoArgsConstructor
@AllArgsConstructor
@Accessors(chain = true)
public class ApiResult<T> implements Serializable {

    private static final long serialVersionUID = 5939135383954522890L;

    private int code;

    private String message;

    private T data;

    public ApiResult(ErrorCode errorCode) {
        errorCode = Optional.ofNullable(errorCode).orElse(ErrorCode.FAILED);
        this.code = errorCode.getCode();
        this.message = errorCode.getMessage();
    }

    public static <T> ApiResult<T> ok() {
        return restResult(null, ErrorCode.SUCCESS);
    }

    public static <T> ApiResult<T> ok(T data) {
        return restResult(data, ErrorCode.SUCCESS);
    }

    public static <T> ApiResult<T> ok(T data, String message) {
        return restResult(data, ErrorCode.SUCCESS.getCode(), message);
    }

    public static <T> ApiResult<T> failed() {
        return restResult(null, ErrorCode.FAILED);
    }

    public static <T> ApiResult<T> failed(String message) {
        return restResult(null, ErrorCode.FAILED.getCode(), message);
    }

    public static <T> ApiResult<T> failed(int code, String message) {
        return restResult(null, code, message);
    }

    public static <T> ApiResult<T> failed(ErrorCode errorCode) {
        return restResult(null, errorCode);
    }

    public static <T> ApiResult<T> failed(ErrorCode errorCode, String message) {
        return restResult(null, errorCode.getCode(), message);
    }

    public static <T> ApiResult<T> restResult(T data, ErrorCode errorCode) {
        return restResult(data, errorCode.getCode(), errorCode.getMessage());
    }

    private static <T> ApiResult<T> restResult(T data, int code, String message) {
        ApiResult<T> apiResult = new ApiResult();
        apiResult.setCode(code);
        apiResult.setData(data);
        apiResult.setMessage(message);
        return apiResult;
    }

    public boolean isSuccess() {
        return ErrorCode.SUCCESS.getCode() == this.code;
    }

    public T serviceData() {
        if (!this.isSuccess()) {
            throw new BusinessException(this.message);
        } else {
            return this.data;
        }
    }
}
